package com.yanqu.road.server.manager.union.trade;

import com.alibaba.fastjson.JSON;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.enums.union.trade.eUnionTradeEventType;
import com.yanqu.road.entity.enums.union.trade.eUnionTradeFinishType;
import com.yanqu.road.entity.enums.union.trade.eUnionTradeLogType;
import com.yanqu.road.entity.enums.union.trade.eUnionTradeRouteState;
import com.yanqu.road.entity.log.cross.LogUnionTradeEventReward;
import com.yanqu.road.entity.log.cross.LogUnionTradeSendPatronsLog;
import com.yanqu.road.entity.player.CrossUserBaseInfo;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.servercenter.ServerInfo;
import com.yanqu.road.entity.union.UnionInfo;
import com.yanqu.road.entity.union.UnionUpgradeInfo;
import com.yanqu.road.entity.union.cross.CrossUnionInfo;
import com.yanqu.road.entity.union.cross.CrossUnionMember;
import com.yanqu.road.entity.union.cross.CrossUnionServerGroup;
import com.yanqu.road.entity.union.trade.*;
import com.yanqu.road.logic.bussiness.union.cross.CrossUnionTradeBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.pb.CrossUnionPb;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.pb.union.UnionTradeProto;
import com.yanqu.road.pb.union.cross.CrossUnionProto;
import com.yanqu.road.pb.worldmessage.WorldMessageProto;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.log.CrossAutoLogMgr;
import com.yanqu.road.server.manager.player.WorldMessageMgr;
import com.yanqu.road.server.manager.union.*;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.manger.CrossUnionServerGroupMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.LocalDateTimeHelper;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 商会贸易（商贸）
 */
public class CrossUnionTradeMgr extends TempMgr {

    /**
     * 计算精度
     */
    public static final int CALCULATION_SCALE = 10;

    private static Logger logger = LogManager.getLogger(CrossUnionTradeMgr.class.getName());

    //unionUid   routeId
    private static Map<String, Map<Integer, UnionTradeTeamData>>    unionTradeTeamDataMap;   //商贸队伍

    //unionUid
    private static Map<String, CrossUnionTradeRouteUnLockData> unionTradeRouteUnLockDataMap;      //商贸路线

    public static final int ROUTE_OPEN_NUM_ONE_DAY = 1;    //路线每日开启次数，暂定

    @Override
    public boolean reloadData() throws Exception {
        unionTradeTeamDataMap = CrossUnionTradeBussiness.getUnionTradeTeamDataMap();

        unionTradeRouteUnLockDataMap = CrossUnionTradeBussiness.getUnionTradeRouteUnLockDataMap();
        return true;
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return false;
    }

    @Override
    public boolean save() {
        for(Map<Integer, UnionTradeTeamData> teamDataMap : unionTradeTeamDataMap.values()){
            for(UnionTradeTeamData teamData : teamDataMap.values()){
                if(teamData.isInsertOption()){
                    CrossUnionTradeBussiness.addUnionTradeTeamData(teamData);
                }else if(teamData.isUpdateOption()){
                    CrossUnionTradeBussiness.updateUnionTradeTeamData(teamData);
                }
            }
        }

        for (Map.Entry<String, CrossUnionTradeRouteUnLockData> entry : unionTradeRouteUnLockDataMap.entrySet()) {
            if(entry.getValue().isInsertOption()){
                CrossUnionTradeBussiness.addUnionTradeRouteUnLockData(entry.getValue());
            }else if(entry.getValue().isUpdateOption()){
                CrossUnionTradeBussiness.updateUnionTradeRouteUnLockData(entry.getValue());
            }
        }
        return true;
    }

    //获取商会商贸队伍
    public static Map<Integer, UnionTradeTeamData> getTeamDataMapByUnionUid(String unionUid){
        Map<Integer, UnionTradeTeamData> map = unionTradeTeamDataMap.get(unionUid);
        if(map == null){
            synchronized (unionTradeTeamDataMap) {
                map = unionTradeTeamDataMap.get(unionUid);
                if(map == null) {
                    map = new ConcurrentHashMap<>();
                    unionTradeTeamDataMap.put(unionUid, map);
                }
            }
        }
        return map;
    }

    //获取商贸路线队伍
    public static UnionTradeTeamData getTeamDataByUnionUinAndRouteId(String unionUid, int routeId){
        return getTeamDataMapByUnionUid(unionUid).get(routeId);
    }

    //是否已解锁路线
    public static boolean isRouteUnlock(UnionTradeRouteInfo routeInfo, UnionInfo unionInfo){
        if(routeInfo.getType() == 2){
            return isUnLockHiddenRoute(routeInfo.getId(), unionInfo);
        }
        return CrossUnionConfigMgr.getUnionLv(unionInfo.getExperience()) >= Integer.valueOf(routeInfo.getUnlock());
    }

    //是否解锁隐藏路线
    public static boolean isUnLockHiddenRoute(int routeId, UnionInfo unionInfo){
        Map<Integer, UnionTradeRouteInfo> routeMap = getUnLockHiddenRoute(unionInfo.getUnionUid());
        return routeMap.containsKey(routeId);
    }

    //获取已解锁的隐藏路线
    public static Map<Integer, UnionTradeRouteInfo> getUnLockHiddenRoute(String unionUid){
        Map<Integer, UnionTradeRouteInfo> routeMap = new HashMap<>();
        CrossUnionTradeRouteUnLockData unLockData = unionTradeRouteUnLockDataMap.get(unionUid);
        if(unLockData == null){
            return routeMap;
        }
        int now = DateHelper.getCurrentSecond();
        for (int i = 0; i < unLockData.getRouteExpiryList().size(); i++) {
            UnionTradeHiddenRouteExpiry routeExpiry = unLockData.getRouteExpiryList().get(i);
            if(routeExpiry.getExpiryTime() <= now && !routeExpiry.isOpen()){
                continue;
            }
            UnionTradeRouteInfo routeInfo = CrossUnionConfigMgr.getUnionTradeRouteInfo(routeExpiry.getRouteId());
            if(routeInfo != null){
                routeMap.put(routeExpiry.getRouteId(), routeInfo);
            }
        }
        return routeMap;
    }

    public static Map<Integer, List<UnionTradeHiddenRouteExpiry>> getUnLockHiddenUnOpenRouteNum(String unionUid){
        Map<Integer, List<UnionTradeHiddenRouteExpiry>> routeNumMap = new HashMap<>();
        CrossUnionTradeRouteUnLockData unLockData = unionTradeRouteUnLockDataMap.get(unionUid);
        if(unLockData == null){
            return routeNumMap;
        }
        int now = DateHelper.getCurrentSecond();
        for (int i = 0; i < unLockData.getRouteExpiryList().size(); i++) {
            UnionTradeHiddenRouteExpiry routeExpiry = unLockData.getRouteExpiryList().get(i);
            if(routeExpiry.getExpiryTime() <= now && !routeExpiry.isOpen()){
                continue;
            }
            if(routeExpiry.isOpen()){
                continue;
            }
            routeNumMap.putIfAbsent(routeExpiry.getRouteId(), new ArrayList<>());
            routeNumMap.get(routeExpiry.getRouteId()).add(routeExpiry);
        }
        return routeNumMap;
    }

    //获取隐藏路线的开启期限
    public static int getHiddenRouteOpenLimitTime(String unionUid, int routeId){
        int expiryTime = DateHelper.getCurrentSecond();
        CrossUnionTradeRouteUnLockData unLockData = unionTradeRouteUnLockDataMap.get(unionUid);
        if(unLockData == null){
            return expiryTime;
        }
        for (int i = 0; i < unLockData.getRouteExpiryList().size(); i++) {
            UnionTradeHiddenRouteExpiry routeExpiry = unLockData.getRouteExpiryList().get(i);
            if(routeExpiry.getRouteId() != routeId || routeExpiry.isOpen()){
                continue;
            }
            return routeExpiry.getExpiryTime();
        }
        return expiryTime;
    }

    //解锁隐藏路线
    public static void addUnionTradeHiddenRouteUnLock(String unionUid, int routeId){
        CrossUnionTradeRouteUnLockData unLockData = unionTradeRouteUnLockDataMap.get(unionUid);
        if(unLockData == null){
            synchronized (unionTradeRouteUnLockDataMap){
                unLockData = unionTradeRouteUnLockDataMap.get(unionUid);
                if(unLockData == null){
                    unLockData = new CrossUnionTradeRouteUnLockData();
                    unLockData.setUnionUid(unionUid);
                    unLockData.setInsertOption();
                    unionTradeRouteUnLockDataMap.put(unionUid, unLockData);
                }
            }
        }
        synchronized (unLockData){
            int now = DateHelper.getCurrentSecond();
            int num = 0;
            Iterator<UnionTradeHiddenRouteExpiry> iterator = unLockData.getRouteExpiryList().iterator();
            while (iterator.hasNext()){
                UnionTradeHiddenRouteExpiry routeExpiry = iterator.next();
                if(routeExpiry.getExpiryTime() > now && !routeExpiry.isOpen()){
                    num++;
                }else if(!routeExpiry.isOpen()){
                    iterator.remove();
                }
            }
            if(num > GameConfig.UNION_STORY_TRADE_EXIST_MAXNUM){
                //同时存在限制
                return;
            }
            unLockData.getRouteExpiryList().add(new UnionTradeHiddenRouteExpiry(routeId, now + GameConfig.UNION_STORY_TRADE_EXIST_TIME * 60));
            unLockData.setUpdateOption();
        }
    }

    /**
     * 获取隐藏路线数量
     */
    public static int getUnionTradeHiddenRouteNum(String unionUid){
        CrossUnionTradeRouteUnLockData unLockData = unionTradeRouteUnLockDataMap.get(unionUid);
        if(unLockData == null){
            return 0;
        }
        int num = 0;
        int now = DateHelper.getCurrentSecond();
        for (UnionTradeHiddenRouteExpiry routeExpiry : unLockData.getRouteExpiryList()) {
            //未过期未开启
            if(routeExpiry.getExpiryTime() > now && !routeExpiry.isOpen()){
                num++;
            }
        }
        return num;
    }

    /**
     * 是否有隐藏路线
     */
    public static boolean hasUnionTradeHiddenRoute(String unionUid, int routeId){
        CrossUnionTradeRouteUnLockData unLockData = unionTradeRouteUnLockDataMap.get(unionUid);
        if(unLockData == null){
            return false;
        }
        int now = DateHelper.getCurrentSecond();
        for (UnionTradeHiddenRouteExpiry routeExpiry : unLockData.getRouteExpiryList()) {
            //未过期且未开启过
            if(routeExpiry.getExpiryTime() > now && routeExpiry.getRouteId() == routeId){
                return true;
            }
        }
        return false;
    }

    /**
     * 开启隐藏路线
     */
    public static void openUnionTradeHiddenRouteUnLock(String unionUid, int routeId){
        CrossUnionTradeRouteUnLockData unLockData = unionTradeRouteUnLockDataMap.get(unionUid);
        if(unLockData == null){
            return;
        }
        int now = DateHelper.getCurrentSecond();
        synchronized (unLockData){
            for (int i = 0; i < unLockData.getRouteExpiryList().size(); i++) {
                UnionTradeHiddenRouteExpiry routeExpiry = unLockData.getRouteExpiryList().get(i);
                if(routeId == routeExpiry.getRouteId() && !routeExpiry.isOpen() && routeExpiry.getExpiryTime() > now){
                    routeExpiry.setOpen(true);
                    unLockData.setUpdateOption();
                    break;
                }
            }
        }
    }

    /**
     * 结束隐藏路线
     */
    public static void subUnionTradeHiddenRouteUnLock(String unionUid, int routeId){
        CrossUnionTradeRouteUnLockData unLockData = unionTradeRouteUnLockDataMap.get(unionUid);
        if(unLockData == null){
            return;
        }
        synchronized (unLockData){
            for (int i = 0; i < unLockData.getRouteExpiryList().size(); i++) {
                UnionTradeHiddenRouteExpiry routeExpiry = unLockData.getRouteExpiryList().get(i);
                if(routeId == routeExpiry.getRouteId() && routeExpiry.isOpen()){
                    unLockData.getRouteExpiryList().remove(i);
                    unLockData.setUpdateOption();
                    break;
                }
            }
        }
    }

    //计算路线当前状态
    public static int calTradeRouteStateVal(UnionTradeRouteInfo routeInfo, UnionTradeTeamData tradeTeamData){
        if(tradeTeamData == null){
            return eUnionTradeRouteState.UnOpen.getIntValue();
        }
        //已结束的不再计算
        if(tradeTeamData.getStateVal() == eUnionTradeRouteState.Close.getIntValue()){
            return eUnionTradeRouteState.Close.getIntValue();
        }
        if(tradeTeamData.getStartTradeTime() == 0 && tradeTeamData.getOpenTime() > 0){
            return eUnionTradeRouteState.UnStart.getIntValue();
        }
        if(tradeTeamData.getStartTradeTime() > 0){
            long pass = DateHelper.getCurrentTime() / 1000 - tradeTeamData.getStartTradeTime();
            if(pass >= (routeInfo.getGoTime() + routeInfo.getReturnTime())){
                return eUnionTradeRouteState.Close.getIntValue();
            }else if(pass >= routeInfo.getGoTime()){
                return eUnionTradeRouteState.Back.getIntValue();
            }else{
                return eUnionTradeRouteState.Trade.getIntValue();
            }
        }
        return eUnionTradeRouteState.UnOpen.getIntValue();
    }

    //检查所有商会路线的状态（定时）
    public static void checkAllUnionTradeRouteState(){
        //logger.info(" check trade state start ");
        long startTimeMillis = System.currentTimeMillis();
        for(Map.Entry<String, Map<Integer, UnionTradeTeamData>>  unionRouteTeamDataEntry : unionTradeTeamDataMap.entrySet()){  //遍历商会
            String unionUid = unionRouteTeamDataEntry.getKey();
            boolean stateChange = false;
            boolean isFinishRoute = false;
            for(Map.Entry<Integer, UnionTradeTeamData> routeTeamDataEntry: unionRouteTeamDataEntry.getValue().entrySet()){   //遍历商队
                int routeId = routeTeamDataEntry.getKey();
                UnionTradeRouteInfo routeInfo = CrossUnionConfigMgr.getUnionTradeRouteInfo(routeId);
                UnionTradeTeamData unionTradeTeamData = routeTeamDataEntry.getValue();
                int oldState = unionTradeTeamData.getStateVal();
                boolean thisRouteChange = checkTradeRouteState(routeInfo, unionTradeTeamData);
                if(!stateChange){    // 避免改变状态被覆盖
                    stateChange = thisRouteChange;
                }
                int newState = unionTradeTeamData.getStateVal();
                if (oldState != newState && newState == eUnionTradeRouteState.Close.getIntValue()) {
                    isFinishRoute = true;
                }
            }
            if(stateChange){
                syncRouteCanJoinToMember(unionUid);
            }
            if (isFinishRoute) {
                // 同步到商会的服务器，并触发本服商会经验冲榜
                try {
                    CrossUnionInfo unionInfo = CrossUnionMgr.getUnionInfo(unionUid);
                    if (unionInfo != null) {
                        CrossUnionProto.UniontTradeAddExpNotifyMsg.Builder syncMsg = CrossUnionProto.UniontTradeAddExpNotifyMsg.newBuilder();
                        syncMsg.setUnionId(unionUid);
                        syncMsg.setUnion(CrossUnionMgr.getCrossUnionTemp(unionInfo));
                        YanQuMessage message = YanQuMessageUtils.buildMessage(GameProtocol.S_UNION_TRADE_EXP_CHANGE_AND_ACTIVITY, syncMsg);
                        MessageHelper.sendPacket(unionInfo.getServerId(),0, message);
                    }
                } catch (Exception e) {
                    logger.error("add trade exp error.", e);
                }
            }
        }
        logger.info(" check trade state end, cost {} ",  System.currentTimeMillis() - startTimeMillis);
    }

    private static boolean checkTradeRouteState(UnionTradeRouteInfo routeInfo, UnionTradeTeamData unionTradeTeamData) {
        boolean stateChange = false;
        synchronized (unionTradeTeamData){
            if(unionTradeTeamData.isSendReward()){
                return false;
            }
            //check old data
            if(unionTradeTeamData.getCondition() <= 0){
                if(unionTradeTeamData.getStartTradeTime() == 0){
                    unionTradeTeamData.setCondition(getRouteCondition(unionTradeTeamData).longValue());
                }else {
                    unionTradeTeamData.setCondition(routeInfo.getCondition());
                }
            }
            if(StringUtils.isNullOrEmpty(unionTradeTeamData.getNewRewards())) {
                if(unionTradeTeamData.getStartTradeTime() == 0){
                    unionTradeTeamData.setNewRewards(getRouteReward(unionTradeTeamData));
                }else {
                    unionTradeTeamData.setNewRewards(routeInfo.getRewards());
                }
            }
            if(unionTradeTeamData.getStateVal() == eUnionTradeRouteState.Close.getIntValue()){
                //改由玩家触发结算
                //但商会解散的情况,无人触发.
                if (unionTradeTeamData.getFinishType() == eUnionTradeFinishType.DeleteUnion.getIntValue()) {
                    //没有任何奖励
                    unionTradeTeamData.setSendReward(true);
                }
                return false;
            }
            int preState = unionTradeTeamData.getStateVal();
            int calState = calTradeRouteStateVal(routeInfo, unionTradeTeamData);
            if(preState != calState && calState == eUnionTradeRouteState.Back.getIntValue()){
                //开始返程计算预计商贸奖励
                calBackExpectReward(routeInfo, unionTradeTeamData);

                if(unionTradeTeamData.getTakeEventIndex() < (unionTradeTeamData.getEventTimeList().size() -1)){
                    //补触发特殊事件
                    triggerTradeEvent(unionTradeTeamData);
                }
            }else if(preState != calState && calState == eUnionTradeRouteState.Close.getIntValue()){
                //关服或者意外情况导致，重新触发事件及返程预计奖励计算
                if(StringUtils.isNullOrEmpty(unionTradeTeamData.getExpectReward())){
                    //预计奖励计算（补偿）
                    calBackExpectReward(routeInfo, unionTradeTeamData);
                }
                if(unionTradeTeamData.getTakeEventIndex() < (unionTradeTeamData.getEventTimeList().size() -1)){
                    //补触发特殊事件
                    triggerTradeEvent(unionTradeTeamData);
                }

                doNormalTradeFinishReward(routeInfo, unionTradeTeamData);
                //unionTradeTeamData.setStateVal(eUnionTradeRouteState.Close.getIntValue());
                //unionTradeTeamData.setFinishType(eUnionTradeFinishType.Normal.getIntValue());
            }else if(preState == calState && calState == eUnionTradeRouteState.Trade.getIntValue()){
                //商贸进行中，触发特殊事件
                triggerTradeEvent(unionTradeTeamData);
            }
            if(preState != calState){
                stateChange = true;
            }
        }
        return stateChange;
    }

    //返回，计算预计奖励（商会奖励比例=总赚钱/路线要求赚钱；玩家奖励=sum(门客赚钱/路线要求赚钱)）
    private static void calBackExpectReward(UnionTradeRouteInfo routeInfo, UnionTradeTeamData unionTradeTeamData) {
        unionTradeTeamData.setStateVal(eUnionTradeRouteState.Back.getIntValue());
        String routeInfoRewards = unionTradeTeamData.getNewRewards();
        Property baseReward = PropertyHelper.parseStringToProperty(routeInfoRewards);  //路线奖励
        Property unionReward = new Property();      //商会奖励
        Property playerReward = new Property();     //玩家奖励
        Property expectReward = new Property();     //预期奖励
        //门客总赚钱
        long allEarn = 0L;
        List<UnionTradeTeamUserJoin> joinDataList = unionTradeTeamData.getUserJoinDataList();
        long routeInfoCondition = unionTradeTeamData.getCondition();
        for(UnionTradeTeamUserJoin joinData : joinDataList){
            //if(joinData.isQuit()) {   //退出也有奖励
            //   continue;
            //}
            allEarn = allEarn + joinData.getPatronsEarn();
            if(allEarn - routeInfoCondition <= 0){
                BigDecimal completePercent = BigDecimal.valueOf(joinData.getPatronsEarn()).divide(BigDecimal.valueOf(routeInfoCondition), CALCULATION_SCALE, BigDecimal.ROUND_UP);
                calExpectReward(baseReward, playerReward, completePercent);
            }else{
                long lastEarn = allEarn - joinData.getPatronsEarn();
                BigDecimal completePercent = BigDecimal.valueOf(routeInfoCondition - lastEarn).divide(BigDecimal.valueOf(routeInfoCondition), CALCULATION_SCALE, BigDecimal.ROUND_UP);
                calExpectReward(baseReward, playerReward, completePercent);
                break;
            }
        }
        //商会奖励
        if(allEarn < routeInfoCondition){
            BigDecimal completePercent = BigDecimal.valueOf(allEarn).divide(BigDecimal.valueOf(routeInfoCondition), CALCULATION_SCALE, BigDecimal.ROUND_UP);
            long count = BigDecimal.valueOf(baseReward.getCountByGoodsId(GameConfig.GAME_ITEM_UNION_EXP).longValue()).multiply(
                    BigDecimal.valueOf(Math.min(1.0, completePercent.doubleValue()))).setScale(0, BigDecimal.ROUND_UP).longValue();
            unionReward.addProperty(GameConfig.GAME_ITEM_UNION_EXP, BigInteger.valueOf(count));
        }else{
            unionReward.addProperty(GameConfig.GAME_ITEM_UNION_EXP, baseReward.getCountByGoodsId(GameConfig.GAME_ITEM_UNION_EXP));
        }
        expectReward.addProperty(unionReward);
        expectReward.addProperty(playerReward);
        unionTradeTeamData.setExpectReward(PropertyHelper.parsePropertyToString(expectReward));
        addLogData(unionTradeTeamData, eUnionTradeLogType.TradeBack, null, null, DateHelper.getCurrentTime(),null);
    }

    private static void calExpectReward(Property baseReward, Property resultReward, BigDecimal completePercent) {
        for (Integer goodsId : baseReward.getGoods().keySet()) {
            if (goodsId.intValue() == GameConfig.GAME_ITEM_UNION_EXP) {
                continue;
            }
            long count = BigDecimal.valueOf(baseReward.getCountByGoodsId(goodsId).longValue()).multiply(
                    BigDecimal.valueOf(Math.min(1.0, completePercent.doubleValue()))).setScale(0, BigDecimal.ROUND_UP).longValue();
            resultReward.addProperty(goodsId, BigInteger.valueOf(count));
        }
    }

    //触发商贸事件
    private static void triggerTradeEvent(UnionTradeTeamData unionTradeTeamData) {
        int index = unionTradeTeamData.getTakeEventIndex();
        long logTime = DateHelper.getCurrentTime();
        int count = 0;
        if(index < unionTradeTeamData.getEventTimeList().size() -1){
            for(index = index + 1; index < unionTradeTeamData.getEventTimeList().size(); index++){
                long gap = DateHelper.getCurrentSecond() - unionTradeTeamData.getStartTradeTime();
                if(gap >= unionTradeTeamData.getEventTimeList().get(index)){
                    count++;
                   int eventId = unionTradeTeamData.getEventList().get(index);
                    UnionTradeEventInfo eventInfo = CrossUnionConfigMgr.getUnionTradeEventInfo(eventId);
                    addLogData(unionTradeTeamData, eUnionTradeLogType.RandomEvent, null, eventInfo, logTime, null);
                }
            }
            if(count > 0) {
                unionTradeTeamData.setTakeEventIndex(count + unionTradeTeamData.getTakeEventIndex());
            }
        }
    }

    //处理正常贸易的奖励
    private static void doNormalTradeFinishReward(UnionTradeRouteInfo routeInfo, UnionTradeTeamData unionTradeTeamData){
        //区服不在线，不让结算
        Set<Long> serverSet = new HashSet<>();
        for (UserBaseInfo baseInfo : unionTradeTeamData.getUserInfoList()) {
            serverSet.add(baseInfo.getServerId());
        }
        //boolean allOnLine = ServerListMgr.isAllServerOnline(serverSet);
        boolean allOnLine = true;
        for (long serverId : serverSet) {
            ServerInfo serverInfo = ServerListMgr.getServerInfo(serverId);
            if(serverInfo == null || serverInfo.getState() == 1){
                allOnLine = false;
                break;
            }
        }
        if(!allOnLine){
            getLogger().info("union trade do finish reward fail, unionUid {}, routeId {}, serverList {}", unionTradeTeamData.getUnionUid(), routeInfo.getId(),
                    JSON.toJSONString(serverSet));
            return;
        }

        unionTradeTeamData.setStateVal(eUnionTradeRouteState.Close.getIntValue());
        unionTradeTeamData.setFinishType(eUnionTradeFinishType.Normal.getIntValue());
        unionTradeTeamData.setSendReward(true);

        long currentTime = DateHelper.getCurrentTime();
        //汇总玩家事件奖励
        Map<Long, Property> userEventRewardMap = sumRouteEventRewardOfUser(unionTradeTeamData);
        //汇总商会事件奖励
        Property unionEventReward = sumRouteEventRewardOfUnion(unionTradeTeamData);

        Property allTradeReward = new Property();  //汇总商贸奖励
        Property allEventReward = new Property();  //汇总事件奖励
        //计算商贸奖励（按比例）
        Map<Long, Property> userTradeRewardMap = calRouteTradeRewardOfUser(routeInfo, unionTradeTeamData);
        Set<Long> sendedUserSet = new HashSet<>();
        for(Long userId : userTradeRewardMap.keySet()){
            sendedUserSet.add(userId);
            Property userReward = new Property();
            userReward.addProperty(userTradeRewardMap.get(userId));
            userReward.addProperty(userEventRewardMap.get(userId));    //事件

            allTradeReward.addProperty(userTradeRewardMap.get(userId));   //统计
            allEventReward.addProperty(userEventRewardMap.get(userId));
            //sendPlayReward(userId, userReward, MailManager.UNION_TRADE_NORMAL_REWARD_SEND_TITLE, MailManager.UNION_TRADE_NORMAL_REWARD_SEND_CONTENT, routeInfo.getName());
            sendPlayReward(userId, userReward, 0, routeInfo);

        }
        //其他玩家的事件奖励
        for(Long userId : userEventRewardMap.keySet()){
            if(!sendedUserSet.contains(userId)){
                allEventReward.addProperty(userEventRewardMap.get(userId));
                //sendPlayReward(userId, userEventRewardMap.get(userId), MailManager.UNION_TRADE_NORMAL_REWARD_SEND_TITLE, MailManager.UNION_TRADE_NORMAL_REWARD_SEND_CONTENT, routeInfo.getName());
                sendPlayReward(userId, userEventRewardMap.get(userId), 1, routeInfo);
            }
        }

        Property unionReward = new Property();  //商会奖励
        Property expectReward = PropertyHelper.parseStringToProperty(unionTradeTeamData.getExpectReward());
        unionReward.addProperty(GameConfig.GAME_ITEM_UNION_EXP, expectReward.getCountByGoodsId(GameConfig.GAME_ITEM_UNION_EXP));        //商会经验
        allTradeReward.addProperty(unionReward);
        unionReward.addProperty(unionEventReward);

        //商会经验
        CrossUnionMgr.addUnionExp(unionTradeTeamData.getUnionUid(), unionReward.getCountByGoodsId(GameConfig.GAME_ITEM_UNION_EXP).longValue(), eLogMoneyType.Union, eLogMoneyType.UnionTradeReward.getValue());


        String unionUid = unionTradeTeamData.getUnionUid();
   /*     try {
            CrossUnionInfo unionInfo = CrossUnionMgr.getUnionInfo(unionUid);
            if (unionInfo != null) {
                long serverId = unionInfo.getServerId();
                List<ActivityInfo> tempList = AllActivityMgr.getUnionRiseRankActivityList(serverId);
                for (ActivityInfo info : tempList) {
                    CrossUnionActivityRankDataProto.CrossAddUnionTradeExpReqMsg.Builder req = CrossUnionActivityRankDataProto.CrossAddUnionTradeExpReqMsg.newBuilder();
                    req.setActivityId(info.getActivityId());
                    req.setUnionId(unionUid);
                    req.setAddValue(unionReward.getCountByGoodsId(GameConfig.GAME_ITEM_UNION_EXP).longValue());
                    req.setUnionBaseInfo(UnionBasePb.parseUnionBaseTempMsg(CrossUnionMgr.parseUnionBaseInfo(unionInfo)));
                    YanQuMessage message = YanQuMessageUtils.buildMessage(CrossProtocol.C_CROSS_UNION_ACTIVITY_ADD_TRADE_EXP, req);
                    MessageHelper.sendChannelPacket(unionInfo.getServerId(),0, message);
                }
            }
        } catch (Exception e) {
            logger.error("add trade exp error.", e);
        }*/




        allEventReward.addProperty(unionEventReward);
        finishRouteReward(unionTradeTeamData, allTradeReward, allEventReward);

        //运营日志
        for(Long userId : userEventRewardMap.keySet()){  //玩家事件
            CrossAutoLogMgr.add(new LogUnionTradeEventReward(unionUid, userId, routeInfo.getId(), PropertyHelper.parsePropertyToString(userEventRewardMap.get(userId)), eUnionTradeEventType.Player.getIntValue()));
        }
        if(!unionEventReward.isNothing()) {;
            CrossAutoLogMgr.add(new LogUnionTradeEventReward(unionUid, 0L, routeInfo.getId(), PropertyHelper.parsePropertyToString(unionEventReward), eUnionTradeEventType.UnionTeam.getIntValue()));
        }

        subUnionTradeHiddenRouteUnLock(unionTradeTeamData.getUnionUid(), routeInfo.getId());
    }

    //计算玩家商贸奖励
    private static Map<Long, Property> calRouteTradeRewardOfUser(UnionTradeRouteInfo routeInfo, UnionTradeTeamData unionTradeTeamData) {
        //userId
        Map<Long, Property> result = new HashMap<>();
        //队伍详情
        List<UnionTradeTeamUserJoin> unionTradeTeamUserJoinDataList =  unionTradeTeamData.getUserJoinDataList();
        //门客总赚钱
        long allEarn = 0L;
        String routeInfoRewards = unionTradeTeamData.getNewRewards();
        Property baseReward = PropertyHelper.parseStringToProperty(routeInfoRewards);
        //过滤掉商会经验,不分摊给个人玩家
        baseReward.setGood(GameConfig.GAME_ITEM_UNION_EXP, BigInteger.ZERO);
        for(UnionTradeTeamUserJoin userJoinData : unionTradeTeamUserJoinDataList) {
            allEarn = allEarn + userJoinData.getPatronsEarn();   //总赚钱
        }
        long routeInfoCondition = unionTradeTeamData.getCondition();
        if(allEarn > routeInfoCondition){
            allEarn = routeInfoCondition;
        }
        long allEarn2 = 0L;
        for(UnionTradeTeamUserJoin userJoinData : unionTradeTeamUserJoinDataList) {
            allEarn2 = allEarn2 + userJoinData.getPatronsEarn();
            if(allEarn2 - routeInfoCondition <= 0){
                BigDecimal completePercent = BigDecimal.valueOf(userJoinData.getPatronsEarn()).divide(BigDecimal.valueOf(routeInfoCondition), CALCULATION_SCALE, BigDecimal.ROUND_UP);
                calTradeReward(result, baseReward, userJoinData, completePercent);
            }else{
                long lastEarn = allEarn2 - userJoinData.getPatronsEarn();
                BigDecimal completePercent = BigDecimal.valueOf(allEarn - lastEarn).divide(BigDecimal.valueOf(routeInfoCondition), CALCULATION_SCALE, BigDecimal.ROUND_UP);
                calTradeReward(result, baseReward, userJoinData, completePercent);
                break;
            }
        }
        return  result;
    }

    //按比例计算派遣门客的商贸奖励
    private static void calTradeReward(Map<Long, Property> result, Property expectReward, UnionTradeTeamUserJoin userJoinData, BigDecimal completePercent) {
        Property userReward = new Property();
        for (Integer goodsId : expectReward.getGoods().keySet()) {
            if(expectReward.getCountByGoodsId(goodsId).compareTo(BigInteger.ZERO) <= 0){
                continue;
            }
            long count = BigDecimal.valueOf(expectReward.getCountByGoodsId(goodsId).longValue()).multiply(
                    BigDecimal.valueOf(Math.min(1.0, completePercent.doubleValue()))).setScale(0, BigDecimal.ROUND_UP).longValue();
            userReward.addProperty(goodsId, BigInteger.valueOf(count));
        }
        if (result.get(userJoinData.getUserId()) == null) {
            result.put(userJoinData.getUserId(), userReward);
        } else {
            result.get(userJoinData.getUserId()).addProperty(userReward);
        }
    }

    //汇总商会事件奖励
    private static Property sumRouteEventRewardOfUnion(UnionTradeTeamData unionTradeTeamData) {
        Property result = new Property();
        List<UnionTradeLog> logDataList = unionTradeTeamData.getLogDataList();
        for(UnionTradeLog logData : logDataList) {
            if (!isEventLogData(logData.getEventId())) {  //跳过非事件日志
                continue;
            }
            UnionTradeEventInfo eventInfo = CrossUnionConfigMgr.getUnionTradeEventInfo(logData.getEventId());
            if (eventInfo.getType() == eUnionTradeEventType.Player.getIntValue()) {
                continue;                    //跳过玩家事件
            }
            Property reward = PropertyHelper.parseStringToProperty(eventInfo.getRewards());
            result.addProperty(reward);
        }
        return result;
    }
    //是否事件日志
    public static boolean isEventLogData(int eventId){
        return eventId > 1000;
    }

    //汇总玩家事件奖励
    private static Map<Long, Property> sumRouteEventRewardOfUser(UnionTradeTeamData unionTradeTeamData) {
        Map<Long, Property> result = new HashMap<>();
        List<UnionTradeLog> logDataList = unionTradeTeamData.getLogDataList();
        for(UnionTradeLog logData : logDataList){
            if(!isEventLogData(logData.getEventId())){          //跳过非事件日志
                continue;
            }
            UnionTradeEventInfo eventInfo = CrossUnionConfigMgr.getUnionTradeEventInfo(logData.getEventId());
            if(eventInfo.getType() == eUnionTradeEventType.UnionTeam.getIntValue()){
                continue;                            //跳过商会事件
            }
            Property reward = PropertyHelper.parseStringToProperty(eventInfo.getRewards());
            for(Long userId : logData.getEventUserIdsList()){
                //if(quitUserList.contains(userId)){   //退出玩家改为有奖励
                //    continue;
                //}
                if(result.get(userId) == null){
                    result.put(userId, new Property());
                }
                result.get(userId).addProperty(reward);
            }
        }
        return result;
    }

    //获取队伍玩家
    public static Set<Long> getUserIdSet(List<UnionTradeTeamUserJoin> joinList){   //不区分玩家是否退出
        Set<Long> set = new HashSet<>();
        for(UnionTradeTeamUserJoin join : joinList){
            set.add(join.getUserId());
        }
        return set;
    }

    private static void finishRouteReward(UnionTradeTeamData unionTradeTeamData, Property tradeReward, Property eventReward){
        unionTradeTeamData.setReward(PropertyHelper.parsePropertyToString(tradeReward));
        unionTradeTeamData.setEventReward(PropertyHelper.parsePropertyToString(eventReward));
        unionTradeTeamData.setStateVal(eUnionTradeRouteState.Close.getIntValue());
        unionTradeTeamData.setFinishType(eUnionTradeFinishType.Normal.getIntValue());
        unionTradeTeamData.setSendReward(true);
    }

    //发送玩家奖励
    private static void sendPlayReward(long userId, Property userReward,String mailTitle, String mailContent, String routeName){
//        UserInfo userInfo = UserMgr.getUserInfo(userId);
//        String title = MultipleLanguageMgr.getContent(mailTitle, userInfo.getLanguage());
//        String content = MessageFormat.format(MultipleLanguageMgr.getContent(mailContent, userInfo.getLanguage()), MultipleLanguageMgr.getContent(routeName, userInfo.getLanguage()));
//        MailManager.sendMail(userId, eMailType.DAILY.getValue(), PropertyHelper.parsePropertyToString(userReward), content, title);
    }

    //发送玩家奖励
    private static void sendPlayReward(long userId, Property userReward, int rewardType, UnionTradeRouteInfo routeInfo){
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
        if(userBaseInfo != null){
            UnionTradeProto.RouteFinishMailRewardSyncMsg.Builder rewardMsg = UnionTradeProto.RouteFinishMailRewardSyncMsg.newBuilder();
            rewardMsg.setRewardType(rewardType);
            rewardMsg.setRouteId(routeInfo.getId());
            rewardMsg.setUserId(userId);
            rewardMsg.setRouteName(routeInfo.getName());
            rewardMsg.setReward(PropertyHelper.parsePropertyToString(userReward));
            MessageHelper.sendPacket(userBaseInfo.getServerId(), userId, YanQuMessageUtils.buildMessage(Protocol.S_UNION_TRADE_ROUTE_REWARD_FROM_CROSS, rewardMsg));

            //奖励日志
            CrossUnionLogMgr.addLogCrossUserReward(userId, userBaseInfo.getServerId(), 0, rewardType, rewardMsg.getReward(), routeInfo.getId() + "");
        }
    }


    public static void addLogData(UnionTradeTeamData unionTradeTeamData, eUnionTradeLogType logType, CrossUnionMember member) {
        addLogData(unionTradeTeamData, logType, member, null, 0, null);
    }

    //添加商贸日志
    public static void addLogData(UnionTradeTeamData unionTradeTeamData, eUnionTradeLogType logType, CrossUnionMember member, UnionTradeEventInfo tradeEventInfo, long logTime, List<UnionTradeTeamUserJoin> newJoinDataList) {
        if(eUnionTradeLogType.OpenRoute.getIntValue() == logType.getIntValue()) {
            //记录路线开启日志
            UnionTradeLog logData = new UnionTradeLog();
            logData.setAddTime(unionTradeTeamData.getOpenTime());
            logData.setEventId(1);
            logData.addLogParams(member.getUserBaseInfo().getNickName());
            unionTradeTeamData.addLogData(logData);
        }else if(eUnionTradeLogType.UserJoin.getIntValue() == logType.getIntValue() || eUnionTradeLogType.UserQuit.getIntValue() == logType.getIntValue()){
            UnionTradeLog logData = new UnionTradeLog();
            logData.addLogParams(member.getUserBaseInfo().getNickName());
            if(eUnionTradeLogType.UserJoin.getIntValue() == logType.getIntValue()){
                logData.setEventId(2);
                logData.addLogParams(String.valueOf(newJoinDataList.size()));
            }else{
                logData.setEventId(4);
            }
            logData.setAddTime(logTime);
            unionTradeTeamData.addLogData(logData);
        }else if(eUnionTradeLogType.RandomEvent.getIntValue() == logType.getIntValue()){
            UnionTradeLog logData = new UnionTradeLog();
            logData.setAddTime(logTime);
            logData.setEventId(tradeEventInfo.getId());
            //随机人员
            int num = tradeEventInfo.getRewardsNum();
            Set<Long> teamMembers = getUserIdSet(unionTradeTeamData.getUserJoinDataList());
            List<Long> userIdList = getRandomNumFromCollection(teamMembers, num);
            List<String> userNameList = new ArrayList<>();

            for(Long userId : userIdList){
                CrossUserBaseInfo crossUserBaseInfo = CrossUserMgr.getCrossUserBaseInfo(userId);
                if (crossUserBaseInfo != null) {
                    userNameList.add(crossUserBaseInfo.getUserBaseInfo().getNickName());
                } else {
                    userNameList.add(userId + "");
                }
            }
            if(tradeEventInfo.getType() == eUnionTradeEventType.Player.getIntValue()) {
                logData.addLogParams(StringUtils.listToString(userNameList, ","));
            }
            logData.setEventUserIdsList(userIdList);
            logData.addLogParams(tradeEventInfo.getRewards());
            unionTradeTeamData.addLogData(logData);
        }else if(eUnionTradeLogType.TradeBack.getIntValue() == logType.getIntValue()){
            UnionTradeLog logData = new UnionTradeLog();
            logData.setAddTime(logTime);
            logData.setEventId(3);
            logData.addLogParams(unionTradeTeamData.getExpectReward());
            unionTradeTeamData.addLogData(logData);
        }
    }

    //获取玩家在特定路线的派遣门客信息
    public static List<Integer> findPatronsByRouteIdAndUserId(String unionUid, int routeId, long userId){
        List<Integer> result = new ArrayList<>();
        UnionTradeTeamData unionTradeTeamData = getTeamDataByUnionUinAndRouteId(unionUid, routeId);
        if(unionTradeTeamData != null){
            List<UnionTradeTeamUserJoin> joinList =  unionTradeTeamData.getNewUserJoinDataList();
            for(UnionTradeTeamUserJoin userJoin : joinList){
                if(userJoin.getUserId() == userId){
                    result.add(userJoin.getPatronsId());
                }
            }
        }
        return result;
    }

    private static List<Long> getRandomNumFromCollection(Set<Long> teamMembers, int num) {
        if(num >= teamMembers.size()) {
            return new ArrayList<>(teamMembers);
        }
        List<Long> idList = new ArrayList<>();
        RandomHelper randomHelper = new RandomHelper();
        while (num > 0){
            Long val = (Long)randomHelper.randomList(teamMembers);
            idList.add(val);
            teamMembers.remove(val);
            num--;
        }
        return idList;
    }

    //通知用户退出商会
    public static void notifyUserQuitUnion(long userId, String unionUid){
        Map<Integer, UnionTradeTeamData>  tradeTeamDataMap = getTeamDataMapByUnionUid(unionUid);
        for(UnionTradeTeamData tradeTeamData : tradeTeamDataMap.values()){
            synchronized (tradeTeamData){
                int calState = calTradeRouteStateVal(CrossUnionConfigMgr.getUnionTradeRouteInfo(tradeTeamData.getRouteId()), tradeTeamData);   //及时计算下
                if(calState != eUnionTradeRouteState.Trade.getIntValue() && calState != eUnionTradeRouteState.Back.getIntValue()){
                    continue;
                }
                int markQuit = 0;
                List<UnionTradeTeamUserJoin> userJoinDataList = tradeTeamData.getUserJoinDataList();
                Set<Long> teamUsers = getUserIdSet(userJoinDataList);
                if(!teamUsers.contains(userId)){
                    continue;
                }
                Iterator<UnionTradeTeamUserJoin> iterator = userJoinDataList.iterator();
                while (iterator.hasNext()){
                    UnionTradeTeamUserJoin userJoinData = iterator.next();
                    if(userId == userJoinData.getUserId()){
                        userJoinData.setQuit(true);                                                    //标记已退出
                    }
                    if(userJoinData.isQuit()){
                        markQuit++;
                    }
                }
                if(userJoinDataList.size() == markQuit){   //最后一个玩家退出，商贸继续
                    //tradeTeamData.setStateVal(eUnionTradeRouteState.Close.getIntValue());               //当没人时，结束贸易
                    //tradeTeamData.setFinishType(eUnionTradeFinishType.QuitUnion.getIntValue());         //退出导致的商贸结束
                }
                long time = DateHelper.getCurrentTime();
                //addLogData(tradeTeamData, eUnionTradeLogType.UserQuit, UserMgr.getUserInfo(userId), null, time, null);
            }
        }
    }

    //通知商会解散
    public static void notifyUnionDelete(String unionUid){
        Map<Integer, UnionTradeTeamData>  tradeTeamDataMap = getTeamDataMapByUnionUid(unionUid);
        for(UnionTradeTeamData tradeTeamData : tradeTeamDataMap.values()) {
            synchronized (tradeTeamData) {
                int calState = calTradeRouteStateVal(CrossUnionConfigMgr.getUnionTradeRouteInfo(tradeTeamData.getRouteId()), tradeTeamData);   //及时计算下
                if(calState != eUnionTradeRouteState.Trade.getIntValue() && calState != eUnionTradeRouteState.Back.getIntValue()) {
                    tradeTeamData.setFinishType(eUnionTradeFinishType.DeleteUnion.getIntValue());
                    continue;
                }
                tradeTeamData.setFinishType(eUnionTradeFinishType.DeleteUnion.getIntValue());
                tradeTeamData.setStateVal(eUnionTradeRouteState.Close.getIntValue());
            }
        }
    }

    //次数重置
    public static void resetOneDay(){
        for(Map.Entry<String, Map<Integer, UnionTradeTeamData>>  unionRouteTeamDataEntry : unionTradeTeamDataMap.entrySet()) {
            for (Map.Entry<Integer, UnionTradeTeamData> routeTeamDataEntry : unionRouteTeamDataEntry.getValue().entrySet()) {
                UnionTradeTeamData unionTradeTeamData = routeTeamDataEntry.getValue();
                synchronized (unionTradeTeamData) {
                    if (!DateHelper.isToday(new Date(unionTradeTeamData.getRestTime()))) {
                        unionTradeTeamData.setOpenNum(0);   //重置次数
                        unionTradeTeamData.setRestTime(System.currentTimeMillis());
                    }
                }
                resetData(unionTradeTeamData);  //暂时
            }
            //强制下发一次红点(作为补偿开启路线但未有派遣的情况等)
            syncRouteCanJoinToMember(unionRouteTeamDataEntry.getKey());
        }
    }

    public static void resetData(String unionUid){
        for (Map.Entry<Integer, UnionTradeTeamData> routeTeamDataEntry : getTeamDataMapByUnionUid(unionUid).entrySet()) {
            UnionTradeTeamData unionTradeTeamData = routeTeamDataEntry.getValue();
            resetData(unionTradeTeamData);
        }
    }

    //暂时，隔天重置数据，待客户端使用开启次数判定是否可以开启时去掉
    private static void resetData(UnionTradeTeamData unionTradeTeamData) {
        synchronized (unionTradeTeamData) {
            if (unionTradeTeamData.getStateVal() != eUnionTradeRouteState.Close.getIntValue()) {
                return;
            }
            if (unionTradeTeamData.getFinishType() == eUnionTradeFinishType.DeleteUnion.getIntValue()){
                return;     //解散的商会，路线不重置
            }
            if (!unionTradeTeamData.isSendReward()) {
                return;
            }
            if (unionTradeTeamData.getOpenTime() > LocalDateTimeHelper.getZeroTimeTimeStamp()) {
                //跳过当天开启
                return;
            }
            unionTradeTeamData.reset();
        }
    }

    public static void syncRouteCanJoinToMember(String unionUid){
        try {
            Map<Long, CrossUnionMember> unionMemberMap = CrossUnionMgr.getUnionMemberMap(unionUid);
            if(unionMemberMap == null){
                return;
            }
            for (Map.Entry<Long, CrossUnionMember> entry : unionMemberMap.entrySet()) {
                syncRouteCanJoinToMember(unionUid, entry.getValue());
            }
        }catch (Exception e){
            logger.error("send union trade red hot error." + e.getMessage(), e);
        }
    }

    public static void syncRouteCanJoinToMember(String unionUid, CrossUnionMember member) {
        boolean canJoin = hasRouteCanJoin(unionUid, member);
        WorldMessageProto.RedHotNotifyMsg.Builder redHotMsg = parseRedHotNotifyMsg(eRedHotNotifyType.UnionTradeCanJoin.getValue(), canJoin == true ? 1 : 0, null);
        MessageHelper.sendPacket(member.getServerId(), member.getUserId(), YanQuMessageUtils.buildMessage(Protocol.U_RED_HOT_NOTIFY, redHotMsg));
    }

    public static boolean hasRouteCanJoin(String unionUid, CrossUnionMember member) {
        //是否还有未派遣的门客
//        int sendNum = 0;
//        List<UserPatrons>  userPatronsList = player.getModule(PatronsModule.class).getUserPatronsList();
//        for(UserPatrons userPatrons : userPatronsList){
//            if(userPatrons.isUnionTradeSend()) {
//                sendNum ++;
//            }
//        }
//        if(sendNum == userPatronsList.size()){
//            return false;   //无门客派遣   不能加入
//        }
        CrossUnionInfo unionInfo = CrossUnionMgr.getUnionInfo(unionUid);
        boolean canJoin = false;
        UnionTradeTeamData teamData = null;
        Map<Integer, UnionTradeTeamData> unionTradeTeamDataMap = CrossUnionTradeMgr.getTeamDataMapByUnionUid(unionUid);
        for(int routeId : unionTradeTeamDataMap.keySet()) {
            teamData = unionTradeTeamDataMap.get(routeId);
            synchronized (teamData){
                if (teamData.getStateVal() == eUnionTradeRouteState.UnStart.getIntValue()) {
                    canJoin = true;
                    break;
                }
                if (teamData.getStateVal() == eUnionTradeRouteState.Close.getIntValue() || teamData.getStateVal() == eUnionTradeRouteState.UnOpen.getIntValue()
                        || teamData.getStateVal() == eUnionTradeRouteState.Back.getIntValue()) {
                    //结束\未开启\返程均不能参加
                    continue;
                }
                //商贸中
                //人数上限
                Set<Long> userIdList = CrossUnionTradeMgr.getUserIdSet(teamData.getUserJoinDataList());
                if (userIdList.contains(member.getUserId())) {
                    continue;   //已参与
                }

                UnionUpgradeInfo unionUpgradeInfo = CrossUnionConfigMgr.getUnionUpgradeInfo(unionInfo.getExperience());
                if (unionUpgradeInfo == null) {
                    logger.error("union trade red hot sync, unionUpgradeInfo is null");
                    continue;
                }
                int crossServerCount = CrossUnionServerGroupMgr.getGroupServerCountByServerId(unionInfo.getServerId());
                if (userIdList.size() >= CrossUnionConfigMgr.getMaxMemberCount(unionInfo.getExperience(), unionInfo.isCross(), crossServerCount)) {
                    continue;    //人数超了
                }
                //赚钱超了
                UnionTradeRouteInfo routeInfo = CrossUnionConfigMgr.getUnionTradeRouteInfo(routeId);
                if (routeInfo != null) {
                    int len = teamData.getUserJoinDataList().size();
                    long allEarn = 0L;
                    for (int i = 0; i < len; i++) {
                        allEarn += teamData.getUserJoinDataList().get(i).getPatronsEarn();
                    }
                    long routeInfoCondition = teamData.getCondition();
                    if (allEarn < routeInfoCondition) {
                        canJoin = true;
                        break;
                    }
                }
            }
        }
        return canJoin;
    }

    public static WorldMessageProto.RedHotNotifyMsg.Builder parseRedHotNotifyMsg(int type, int count, String param){
        WorldMessageProto.RedHotNotifyMsg.Builder msg = WorldMessageProto.RedHotNotifyMsg.newBuilder();
        msg.setType(type);
        msg.setCount(count);
        if(!StringUtils.isNullOrEmpty(param)){
            msg.setParam(param);
        }
        return msg;
    }

    //cross
    //获取路线最新状态（routeId, 0表示全部路线；teamDetail  是否包含队伍详情）
    public static UnionTradeProto.RouteListRespMsg.Builder getNewestUnionRouteData(int  routeId, boolean teamDetail, CrossUnionInfo unionInfo, CrossUnionMember member){

        //log.info(" getNewestUnionRouteData start ");
        long startTimeMillis = System.currentTimeMillis();
        String unionUid = member.getUnionUid();

        UnionTradeProto.RouteListRespMsg.Builder respMsg = UnionTradeProto.RouteListRespMsg.newBuilder();
        //路线
        Map<Integer, UnionTradeRouteInfo> routeInfoMap =  CrossUnionConfigMgr.getUnionTradeRouteInfoMap();
        //隐藏路线
        if(unionInfo.isCross()){
            routeInfoMap.putAll(getUnLockHiddenRoute(unionInfo.getUnionUid()));
        }

        //缓存隐藏路线
        List<Integer> hidedRouteList = new ArrayList<>();
        List<UnionTradeProto.RouteTempMsg.Builder> tempList = new ArrayList<>();
        //优先-补充隐藏的路线
        Map<Integer, List<UnionTradeHiddenRouteExpiry>> numMap = getUnLockHiddenUnOpenRouteNum(unionInfo.getUnionUid());
        for (Map.Entry<Integer, List<UnionTradeHiddenRouteExpiry>> entry : numMap.entrySet()) {
            for (UnionTradeHiddenRouteExpiry expiry : entry.getValue()) {
                UnionTradeProto.RouteTempMsg.Builder routeMsg = UnionTradeProto.RouteTempMsg.newBuilder();
                routeMsg.setRouteId(expiry.getRouteId());
                routeMsg.setStateVal(eUnionTradeRouteState.UnOpen.getIntValue());
                routeMsg.setOpenLimitTime(expiry.getExpiryTime());
                tempList.add(routeMsg);
                hidedRouteList.add(expiry.getRouteId());
            }
        }

        //队伍
        Map<Integer, UnionTradeTeamData> teamDataMap = getTeamDataMapByUnionUid(unionUid);
        for(UnionTradeRouteInfo routeInfo : routeInfoMap.values()){
            if(routeId != 0){//不为0代表只查询指定线路
                if(routeId != routeInfo.getId()){
                    continue;
                }
            }
            UnionTradeProto.RouteTempMsg.Builder routeMsg = UnionTradeProto.RouteTempMsg.newBuilder();
            routeMsg.setRouteId(routeInfo.getId());
            //是否解锁
            if(isRouteUnlock(routeInfo, unionInfo)){
                routeMsg.setStateVal(eUnionTradeRouteState.UnOpen.getIntValue());
            }else{
                routeMsg.setStateVal(eUnionTradeRouteState.Locked.getIntValue());
                if(routeInfo.getType() == 2){
                    continue;
                }
            }
            //解锁状态下，查询队伍信息
            if(routeMsg.getStateVal() != eUnionTradeRouteState.Locked.getIntValue()){
                UnionTradeTeamData teamData = teamDataMap.get(routeInfo.getId());
                if(teamData != null){
                    UnionTradeProto.TeamDataTempMsg.Builder  teamMsg  = UnionTradeProto.TeamDataTempMsg.newBuilder();
                    int calState;
                    synchronized (teamData){
                        calState = calTradeRouteStateVal(routeInfo, teamData);
                    }
                    //未解锁过隐藏路线时，已结束、未开启，优先显示隐藏的路线（避免记录的数据与配置冲突）
                    if((calState == eUnionTradeRouteState.UnOpen.getIntValue() || calState == eUnionTradeRouteState.Close.getIntValue()) && hidedRouteList.contains(teamData.getRouteId())){
                        continue;
                    }
                    routeMsg.setStateVal(calState);
                    teamMsg.setStateVal(calState);
                    //队伍详情
                    List<UnionTradeTeamUserJoin> unionTradeTeamUserJoinDataList = teamData.getNewUserJoinDataList();
                    teamMsg.setOpenTime(teamData.getOpenTime());
                    teamMsg.setStartTradeTime(Long.valueOf(teamData.getStartTradeTime()).intValue());
                    long earn = 0L;
                    for(UnionTradeTeamUserJoin joinData : unionTradeTeamUserJoinDataList){
                        earn = earn + joinData.getPatronsEarn();
                    }
                    teamMsg.setPatronsEarns(earn);
                    if(!StringUtils.isNullOrEmpty(teamData.getExpectReward())) {
                        teamMsg.setExpectReward(teamData.getExpectReward());
                    }
                    if(teamDetail){
                        for(UnionTradeTeamUserJoin userJoinData : unionTradeTeamUserJoinDataList){
                            //if(userJoinData.isQuit()){   //退出门客也要显示在列表
                            //    continue;
                            //}
                            UnionTradeProto.TeamUserPatronsTempMsg.Builder userPatronsMsg =   UnionTradeProto.TeamUserPatronsTempMsg.newBuilder();
                            userPatronsMsg.setUserId(userJoinData.getUserId());
                            userPatronsMsg.setUserAliasId(userJoinData.getUserAliasId());
                            userPatronsMsg.setDecoration(userJoinData.getDecoration());
                            userPatronsMsg.setSkinId(userJoinData.getSkinId());
                            userPatronsMsg.setJoinTime(userJoinData.getJoinTime());
                            userPatronsMsg.setPatronsId(userJoinData.getPatronsId());
                            userPatronsMsg.setPatronsEarns(userJoinData.getPatronsEarn());
                            teamMsg.addUserPatronsJoinList(userPatronsMsg);
                        }
                    }
                    if(teamData.getStateVal() == eUnionTradeRouteState.Close.getIntValue() && teamData.isSendReward()){
                        teamMsg.setCanOpen(ROUTE_OPEN_NUM_ONE_DAY > teamData.getOpenNum());   //结束商队是否可开启
                    }
                    List<UserBaseInfo> userBaseInfoList = teamData.getNewUserInfoList();
                    for(UserBaseInfo userBaseInfo : userBaseInfoList){
                        teamMsg.addUserInfoList(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
                    }
                    if(calState >= eUnionTradeRouteState.UnStart.getIntValue() && calState <= eUnionTradeRouteState.Back.getIntValue()){
                        teamMsg.setCondition(teamData.getCondition());
                        teamMsg.setNewRewards(teamData.getNewRewards());
                    }
                    routeMsg.setTeamData(teamMsg);
                }else {
                    //未解锁过隐藏路线时，优先显示隐藏的路线（避免记录的数据与配置冲突）
                    if(hidedRouteList.contains(routeInfo.getId())){
                        continue;
                    }
                }
                //隐藏线路的开启有效期
                if(routeInfo.getType() == 2){
                    routeMsg.setOpenLimitTime(getHiddenRouteOpenLimitTime(unionUid, routeInfo.getId()));
                }
            }else{
                routeMsg.setStateVal(eUnionTradeRouteState.Locked.getIntValue());
            }
            respMsg.addRouteTempList(routeMsg);
        }

        if(routeId == 0) {
            for (UnionTradeProto.RouteTempMsg.Builder builder : tempList) {
                respMsg.addRouteTempList(builder);
            }
        }

        long dt = System.currentTimeMillis() - startTimeMillis;
        if (dt > 1) {
            getLogger().info(" getNewestUnionRouteData cost {} ", System.currentTimeMillis() - startTimeMillis);
        }
        return respMsg;
    }

    /**
     * 开启商贸
     */
    public static int openTradeRoute(long serverId, long playerId, int routeId, String consume) {
        CrossUnionReqContext context = CrossUnionReqContext.initContext(serverId, playerId).loadUnionMember().loadUnionInfo();

        if(context.getRet() != 0){
            return context.getRet();
        }

        UnionTradeRouteInfo routeInfo = CrossUnionConfigMgr.getUnionTradeRouteInfo(routeId);
        if(null == routeInfo){
            return GameErrorCode.E_UNION_TRADE_ROUTE_NOT_FOUND;
        }

        if(!isRouteUnlock(routeInfo, context.getUnionInfo())){
            return GameErrorCode.E_UNION_TRADE_ROUTE_LOCKED;         //未解锁
        }

        Map<Integer, UnionTradeTeamData> unionTradeTeamDataMap = getTeamDataMapByUnionUid(context.getUnionInfo().getUnionUid());
        UnionTradeTeamData unionTradeTeamData = unionTradeTeamDataMap.get(routeId);

        Object lockObj;
        if(unionTradeTeamData == null){
            lockObj =  unionTradeTeamDataMap;
        }else{
            lockObj =  unionTradeTeamData;
        }
        synchronized (lockObj) {
            boolean isNew = false;
            unionTradeTeamData = unionTradeTeamDataMap.get(routeId);
            if (unionTradeTeamData == null) {
                unionTradeTeamData = new UnionTradeTeamData();
                unionTradeTeamData.setRouteId(routeId);
                unionTradeTeamData.setUnionUid(context.getUnionInfo().getUnionUid());
                unionTradeTeamData.setRestTime(DateHelper.getCurrentTime());
                unionTradeTeamData.setInsertOption();
                isNew = true;
            } else {
                int curState = calTradeRouteStateVal(routeInfo, unionTradeTeamData);   //待客户端按次数判定是否开启时，只需判断结束发奖状态
                if (eUnionTradeRouteState.UnOpen.getIntValue() != curState || (eUnionTradeRouteState.Close.getIntValue() == curState && !unionTradeTeamData.isSendReward())) {
                    return GameErrorCode.E_UNION_TRADE_ROUTE_BEEN_OPENED;
                }
            }

            //是否有开启次数
            if (unionTradeTeamData.getOpenNum() >= ROUTE_OPEN_NUM_ONE_DAY) {
                return GameErrorCode.E_UNION_TRADE_ROUTE_OPEN_NUM_NOT_ENOUGH;
            }

            //重置商队
            unionTradeTeamData.reset();
            unionTradeTeamData.setStateVal(eUnionTradeRouteState.UnStart.getIntValue());
            unionTradeTeamData.setOpenTime(DateHelper.getCurrentTime());
            unionTradeTeamData.setOpenUser(playerId);

            //初始队伍要求及奖励
            BigInteger condition = getRouteCondition(unionTradeTeamData);
            unionTradeTeamData.setCondition(condition.longValue());
            String newRewards = getRouteReward(unionTradeTeamData);
            unionTradeTeamData.setNewRewards(newRewards);

            //次数+1
            unionTradeTeamData.setOpenNum(unionTradeTeamData.getOpenNum() + 1);
            //随机事件初始化  3
            initTradeEventData(routeInfo, unionTradeTeamData);

            if(routeInfo.getType() == 2) {
                openUnionTradeHiddenRouteUnLock(context.getUnionInfo().getUnionUid(), routeId);
            }

            //记录商贸日志
            addLogData(unionTradeTeamData, eUnionTradeLogType.OpenRoute, context.getMember());
            if(isNew) {
                getTeamDataMapByUnionUid(context.getUnionInfo().getUnionUid()).put(routeId, unionTradeTeamData);
            }

            //商会频道消息
            String content = WorldMessageMgr.encodeContent(context.getUserBaseInfo().getUserBaseInfo().getNickName(), consume, routeId);
            WorldMessageProto.WorldMessageTempMsg.Builder chatMsg = WorldMessageMgr.parseWorldMessageTempMsg(context.getUserBaseInfo(),
                    eMessageType.UnionTradeMsg.getValue(), eChatContentType.Common.getContentType(), content, unionTradeTeamData.getOpenTime(), 0, null);
            WorldMessageMgr.sendUnionChat(context.getMember().getServerId(), context.getPlayerId(), chatMsg, context.getUnionInfo().getUnionUid());

            //记录到商会日志
            CrossUserBaseInfo player = CrossUserMgr.getCrossUserBaseInfo(playerId);
            CrossUnionNoticeMgr.addNotice(player, context.getUnionInfo().getUnionUid(), eUnionNoticeType.Trade.getValue(), context.getMember().getUserBaseInfo().getNickName(), consume, routeId);

            //
            UnionTradeProto.RouteOpenCrossRespMsg.Builder crossResp = UnionTradeProto.RouteOpenCrossRespMsg.newBuilder();
            crossResp.setRet(0);
            crossResp.setRouteId(routeId);
            crossResp.setConsume(consume);
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_UNION_TRADE_ROUTE_OPEN_FROM_CROSS, crossResp));
        }

        syncRouteCanJoinToMember(context.getUnionInfo().getUnionUid());  //红点

        return 0;
    }

    //初始路线的随机事件（按时间有序）
    private static void initTradeEventData(UnionTradeRouteInfo routeInfo, UnionTradeTeamData unionTradeTeamData) {
        RandomHelper randomHelper = new RandomHelper();
        int eventNum = randomHelper.next(routeInfo.getEventNum().get(0), 1 + routeInfo.getEventNum().get(1));  //确定路线事件个数
        if(routeInfo.getEventNum().get(1) <= routeInfo.getEventTime().size()) {   //最大值比集合小
            List<Integer> list = randomCollectionOfEvent2(randomHelper, routeInfo.getEventTime(), eventNum);
            Collections.sort(list);
            unionTradeTeamData.setEventTimeList(list);
            unionTradeTeamData.setEventList(randomCollectionOfEvent(randomHelper, routeInfo.getEventList(), eventNum));
            unionTradeTeamData.setTakeEventIndex(-1);
        }
    }

    //随机选取路线事件时间（不重复）
    private static List<Integer> randomCollectionOfEvent2(RandomHelper randomHelper, List<Integer> all, int num){
        List<Integer> result = new ArrayList<>();
        if(num == all.size()){//全量
            result.addAll(all);
        }else {
            List<Integer> fetchList = new ArrayList<>(all);
            for(int i = 0; i < num; i++) {
                int randIndex = randomHelper.next(0, fetchList.size());
                result.add(fetchList.get(randIndex));
                fetchList.remove(randIndex);
            }
        }
        return result;
    }

    //随机选取路线事件
    private static List<Integer> randomCollectionOfEvent(RandomHelper randomHelper, List<Integer> all, int num){
        List<Integer> result = new ArrayList<>();
        if(num == all.size()){//全量
            result.addAll(all);
        }else {
            for(int i = 0; i < num; i++) {
                int randIndex = randomHelper.next(0, all.size());
                result.add(all.get(randIndex));
            }
        }
        return result;
    }

    public static int joinTradeTeam(long serverId, long playerId, int routeId, List<UnionTradeProto.RouteJoinPatronsTemp> patronsList) {

        CrossUnionReqContext context = CrossUnionReqContext.initContext(serverId, playerId).loadUnionMember().loadUnionInfo();

        if(context.getRet() != 0){
            return context.getRet();
        }

        List<Integer> hadSend = CrossUnionTradeMgr.findPatronsByRouteIdAndUserId(context.getUnionInfo().getUnionUid(), routeId, playerId);
        for(UnionTradeProto.RouteJoinPatronsTemp patronsTemp : patronsList){
            if(hadSend.contains(patronsTemp.getPatronsId())) {
                return GameErrorCode.E_UNION_TRADE_ROUTE_HAD_JOIN;          //门客已被派遣过,(避免隔天路线，门客派遣重置造成路线重复派遣)
            }
        }

        UnionTradeTeamData unionTradeTeamData = getTeamDataByUnionUinAndRouteId(context.getUnionInfo().getUnionUid(), routeId);
        UnionTradeRouteInfo unionTradeRouteInfo = CrossUnionConfigMgr.getUnionTradeRouteInfo(routeId);

        int stateVal = calTradeRouteStateVal(unionTradeRouteInfo, unionTradeTeamData);
        if(eUnionTradeRouteState.Trade.getIntValue() != stateVal && eUnionTradeRouteState.UnStart.getIntValue() != stateVal){
            return GameErrorCode.E_UNION_TRADE_ONLY_TRADE_CAN_JOIN;      //只有进行中的商贸与未出发的商贸才可加入
        }

        synchronized (unionTradeTeamData){
            stateVal = calTradeRouteStateVal(unionTradeRouteInfo, unionTradeTeamData);
            if(eUnionTradeRouteState.Trade.getIntValue() != stateVal && eUnionTradeRouteState.UnStart.getIntValue() != stateVal){
                return GameErrorCode.E_UNION_TRADE_ONLY_TRADE_CAN_JOIN;      //只有进行中的商贸与未出发的商贸才可加入
            }

            hadSend = CrossUnionTradeMgr.findPatronsByRouteIdAndUserId(context.getUnionInfo().getUnionUid(), routeId, playerId);
            for(UnionTradeProto.RouteJoinPatronsTemp patronsTemp : patronsList){
                if(hadSend.contains(patronsTemp.getPatronsId())) {
                    return GameErrorCode.E_UNION_TRADE_ROUTE_HAD_JOIN;          //门客已被派遣过,(避免隔天路线，门客派遣重置造成路线重复派遣)
                }
            }

            //人数上限
            Set<Long> userIdList = getUserIdSet(unionTradeTeamData.getUserJoinDataList());

            //UnionUpgradeInfo unionUpgradeInfo = CrossUnionConfigMgr.getUnionUpgradeInfo(context.getUnionInfo().getExperience());
            int crossServerCount = CrossUnionServerGroupMgr.getGroupServerCountByServerId(context.getUnionInfo().getServerId());
            if(userIdList.size() >= CrossUnionConfigMgr.getMaxMemberCount(context.getUnionInfo().getExperience(), context.getUnionInfo().isCross(), crossServerCount)
                    && !userIdList.contains(playerId)){
                return GameErrorCode.E_UNION_TRADE_ROUTE_TEAM_USER_NUM_EXCEED;
            }

            long allEarns = 0L;
            for(UnionTradeTeamUserJoin joinData : unionTradeTeamData.getUserJoinDataList()){
                allEarns += joinData.getPatronsEarn();
            }
            long routeInfoCondition = unionTradeTeamData.getCondition();
            if(routeInfoCondition <= allEarns){
                return GameErrorCode.E_UNION_TRADE_ROUTE_PATRONS_EARN_EXCEED;      //赚钱超出队伍要求
            }
            long currentTime = DateHelper.getCurrentTime();
            List<UnionTradeTeamUserJoin> newJoinDataList = new ArrayList<>();
            CrossUserBaseInfo baseInfo = CrossUserMgr.getCrossUserBaseInfo(playerId);
            List<Integer> patronsIdList = new ArrayList<>();
            for(UnionTradeProto.RouteJoinPatronsTemp patronsTemp : patronsList) {
                UnionTradeTeamUserJoin userJoinData =  new UnionTradeTeamUserJoin();
                //UserPatrons userPatrons = player.getModule(PatronsModule.class).getUserPatrons(patronsId);
                BigInteger patronsEarn = new BigInteger(patronsTemp.getAbility());
                userJoinData.setPatronsEarn(patronsEarn.longValue());
                userJoinData.setPatronsId(patronsTemp.getPatronsId());
                userJoinData.setUserId(playerId);
                userJoinData.setJoinTime(currentTime);
                userJoinData.setSkinId(patronsTemp.getSkinId());
                userJoinData.setUserAliasId(baseInfo.getUserBaseInfo().getUserAliasId());
                userJoinData.setDecoration(baseInfo.getUserBaseInfo().getDecoration());
                newJoinDataList.add(userJoinData);
                patronsIdList.add(patronsTemp.getPatronsId());
            }
            int oldSize = unionTradeTeamData.getUserJoinDataList().size();
            //是否第一个加入
            if (oldSize == 0) {
                unionTradeTeamData.setStateVal(eUnionTradeRouteState.Trade.getIntValue());
                unionTradeTeamData.setStartTradeTime(currentTime/1000);
            }
            unionTradeTeamData.addAllJoinData(newJoinDataList);

            //标记门客已派遣
//            Map<Integer, UserPatrons> userPatronsMap = player.getModule(PatronsModule.class).getUserPatronsMap();
//            for(Integer patronsId : patronsIdList){
//                userPatronsMap.get(patronsId).setUnionTradeSend(true);
//            }
            //记录商贸日志
            addLogData(unionTradeTeamData, eUnionTradeLogType.UserJoin, context.getMember(), null, currentTime, newJoinDataList);

            //记录玩家详情
            unionTradeTeamData.addUserInfo(context.getUserBaseInfo().getUserBaseInfo());

            //运营日志
            for(UnionTradeTeamUserJoin join : newJoinDataList) {
                //路线等级
                CrossAutoLogMgr.add(new LogUnionTradeSendPatronsLog(context.getUnionInfo().getUnionUid(), playerId, unionTradeRouteInfo.getId(), join.getPatronsId(), join.getPatronsEarn(), ++oldSize));
            }

            UnionTradeProto.PatronsSendCrossRespMsg.Builder builder = UnionTradeProto.PatronsSendCrossRespMsg.newBuilder();
            builder.addAllPatronsId(patronsIdList);
            builder.setRet(0);
            builder.setRouteId(routeId);
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_UNION_TRADE_ROUTE_PATRONS_SEDN_FROM_CROSS, builder));
        }
        CrossUnionTradeMgr.syncRouteCanJoinToMember(context.getUnionInfo().getUnionUid());

        return 0;
    }

    //未读的特殊事件
    public static void syncUnReadEventList(long serverId, long playerId, int routeId){

        CrossUnionReqContext context = CrossUnionReqContext.initContext(serverId, playerId).loadUnionMember().loadUnionInfo();

        if(context.getRet() != 0){
            return;
        }

        UnionTradeTeamData unionTradeTeamData =  getTeamDataByUnionUinAndRouteId(context.getUnionInfo().getUnionUid(), routeId);
        if(unionTradeTeamData != null){
            List<UnionTradeLog> unionTradeLogDataList = unionTradeTeamData.getNewLogDataList();
            List<UnionTradeLog> allEventLogList = new ArrayList<>();
            for(UnionTradeLog logData : unionTradeLogDataList){
                if(isEventLogData(logData.getEventId())){
                    allEventLogList.add(logData);
                }
            }
            if(allEventLogList.size() == 0){
                return;
            }
            List<UnionTradeLog> needSendList = new ArrayList<>();
            List<UnionTradeEventRead>  eventReadList = unionTradeTeamData.getUserReadList();
            Iterator<UnionTradeEventRead> eventReadIterator = eventReadList.iterator();

            UnionTradeEventRead userEventRead = null;
            while(eventReadIterator.hasNext()){
                UnionTradeEventRead eventRead = eventReadIterator.next();
                if (eventRead.getUserId() == playerId) {
                    userEventRead = eventRead;
                }
            }
            if (userEventRead == null) {
                userEventRead = new UnionTradeEventRead(playerId, -1);
                synchronized (eventReadList) {
                    eventReadList.add(userEventRead);
                }
            }

            if (userEventRead.getIdx() == allEventLogList.size() - 1) {
                return;
            }

            for (int i = userEventRead.getIdx() + 1; i < allEventLogList.size(); i++) {
                needSendList.add(allEventLogList.get(i));
            }
            userEventRead.setIdx(allEventLogList.size() - 1);
            unionTradeTeamData.setUpdateOption();
            if(needSendList.size() > 0) {
                UnionTradeProto.UnReadEventListRespMsg.Builder respMsg = UnionTradeProto.UnReadEventListRespMsg.newBuilder();
                respMsg.setRet(0);
                respMsg.addAllLogDataList(CrossUnionPb.parseTradeLogDataTempMsgList(needSendList));

                MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_UNION_TRADE_ROUTE_UNREAD_EVENT_LIST, respMsg));

            }
        }
    }

    //路线开启的开服天数
    public static int getOpenDays(long serverId, long routeOpenTime){
        long openTime = getServerOpenTime(serverId);
        if(openTime <= 0){
            return 0;
        }
        return DateHelper.calc2DateTDOADays(new Date(openTime * 1000), new Date(routeOpenTime));
    }

    public static long getServerOpenTime(long serverId){
        ServerInfo serverInfo = ServerListMgr.getServerInfo(serverId);
        if(serverInfo == null){
            return 0;
        }
        long openTime = serverInfo.getOpenTime();
        //拿分组
        CrossUnionServerGroup serverGroup = CrossUnionServerGroupMgr.getServerGroupByServerId(serverId);
        if(serverGroup != null){
            for (Long sid : serverGroup.getServerList()) {
                ServerInfo info = ServerListMgr.getServerInfo(sid);
                if(info != null){
                    if(info.getOpenTime() < openTime){
                        openTime = info.getOpenTime();
                    }
                }
            }
        }
        return openTime;
    }

    public static int getOpenDays(String unionUid, long routeOpenTime){
        CrossUnionInfo unionInfo = CrossUnionMgr.getUnionInfo(unionUid);
        if(unionInfo == null){
            return 0;
        }
        return getOpenDays(unionInfo.getServerId(), routeOpenTime);
    }

    public static BigInteger getRouteCondition(UnionTradeTeamData unionTradeTeamData){
        OpenDayConfig odc = getOpenDayConditionConfig(unionTradeTeamData);
        if(odc == null){
            return BigInteger.ZERO;
        }
        return new BigInteger(odc.getParam());
    }

    public static String getRouteReward(UnionTradeTeamData unionTradeTeamData){
        OpenDayConfig odc = getOpenDayNewRewardConfig(unionTradeTeamData);
        if(odc == null){
            return "";
        }
        return odc.getParam();
    }

    private static OpenDayConfig getOpenDayConditionConfig(UnionTradeTeamData unionTradeTeamData) {
        UnionTradeRouteInfo routeInfo = CrossUnionConfigMgr.getUnionTradeRouteInfo(unionTradeTeamData.getRouteId());
        int openDays = getOpenDays(unionTradeTeamData.getUnionUid(), unionTradeTeamData.getOpenTime());
        OpenDayConfig odc = null;
        for (OpenDayConfig config : routeInfo.getConditionList()) {
            if (openDays >= config.getStart() && openDays <= config.getEnd()) {
                odc = config;
                break;
            }
        }
        if(odc == null && routeInfo.getConditionList().size() > 0){
            odc = routeInfo.getConditionList().get(routeInfo.getConditionList().size() - 1);
        }
        return odc;
    }

    private static OpenDayConfig getOpenDayNewRewardConfig(UnionTradeTeamData unionTradeTeamData) {
        UnionTradeRouteInfo routeInfo = CrossUnionConfigMgr.getUnionTradeRouteInfo(unionTradeTeamData.getRouteId());
        int openDays = getOpenDays(unionTradeTeamData.getUnionUid(), unionTradeTeamData.getOpenTime());
        OpenDayConfig odc = null;
        for (OpenDayConfig config : routeInfo.getRewardList()) {
            if (openDays >= config.getStart() && openDays <= config.getEnd()) {
                odc = config;
                break;
            }
        }
        if(odc == null && routeInfo.getRewardList().size() > 0){
            odc = routeInfo.getRewardList().get(routeInfo.getRewardList().size() - 1);
        }
        return odc;
    }
}
